import axios from 'axios';
import {
  HotItemBase,
  HotItemDetail,
  HotItemTrend,
  Platform,
  TimeRange,
  ApiResponse,
} from '../types/hotRadar';
import { RateLimiter } from '../utils/throttle';

// Create axios instance with base configuration
const apiClient = axios.create({
  baseURL: import.meta.env.VITE_CRAWLER_API_URL || '/api/v1',
  timeout: 30000,
  headers: {
    'Content-Type': 'application/json',
  },
});

// Request interceptor to add auth token
apiClient.interceptors.request.use(
  (config) => {
    console.log('🔍 [Interceptor] Request config:', {
      method: config.method,
      url: config.url,
      baseURL: config.baseURL,
      headers: config.headers,
      timeout: config.timeout
    });
    
    // Only add auth token for non-public endpoints
    if (!config.url?.includes('/hot-items')) {
      const token = localStorage.getItem('access_token');
      if (token) {
        config.headers.Authorization = `Bearer ${token}`;
      }
    }
    return config;
  },
  (error) => {
    console.log('🔍 [Interceptor] Request error:', error);
    return Promise.reject(error);
  }
);

// Response interceptor for error handling
apiClient.interceptors.response.use(
  (response) => {
    console.log('🔍 [Interceptor] Response received:', {
      status: response.status,
      statusText: response.statusText,
      headers: response.headers,
      dataType: typeof response.data,
      dataSize: JSON.stringify(response.data).length
    });
    return response.data;
  },
  (error) => {
    console.log('🔍 [Interceptor] Error received:', {
      status: error.response?.status,
      statusText: error.response?.statusText,
      message: error.message,
      code: error.code,
      isAxiosError: error.isAxiosError
    });
    
    if (error.response?.status === 401) {
      // Only handle token refresh for authenticated endpoints
      // Skip for public API endpoints like hot-items
      if (!error.config?.url?.includes('/hot-items')) {
        localStorage.removeItem('access_token');
        window.location.href = '/login';
      }
    }
    return Promise.reject(error);
  }
);

export interface GetHotItemsParams {
  page?: number;
  page_size?: number;
  platforms?: Platform[];
  time_range?: TimeRange | { start: string; end: string };
  sort_by?: 'heat' | 'time' | 'rank';
  sort_order?: 'asc' | 'desc';
  keyword?: string;
  category?: string;
}

export interface SearchHotItemsParams {
  keyword: string;
  platforms?: Platform[];
  page?: number;
  page_size?: number;
}

class HotRadarService {
  private rateLimiter: RateLimiter;

  constructor() {
    // Allow 10 requests per second with a burst of 20
    this.rateLimiter = new RateLimiter(20, 10);
  }

  private async waitForRateLimit(): Promise<void> {
    while (!this.rateLimiter.canMakeRequest()) {
      const waitTime = this.rateLimiter.getWaitTime();
      await new Promise(resolve => setTimeout(resolve, waitTime));
    }
  }

  // Get hot items list with filters
  async getHotItems(params: GetHotItemsParams): Promise<ApiResponse<HotItemBase[]>> {
    await this.waitForRateLimit();
    const queryParams = new URLSearchParams();
    
    if (params.page) queryParams.append('page', params.page.toString());
    if (params.page_size) queryParams.append('page_size', params.page_size.toString());
    if (params.platforms?.length) {
      params.platforms.forEach(p => queryParams.append('platforms', p));
    }
    // 不传时间参数，使用后端默认的7天范围
    // 这样可以避免时区和格式解析问题，后端会自动使用最近7天的数据
    // if (params.time_range) {
    //   // 时间筛选逻辑已禁用
    // }
    if (params.sort_by) queryParams.append('sort_by', params.sort_by);
    if (params.sort_order) queryParams.append('sort_order', params.sort_order);
    if (params.keyword) queryParams.append('keyword', params.keyword);
    if (params.category) queryParams.append('category', params.category);

    const requestUrl = `/hot-items?${queryParams.toString()}`;
    const fullUrl = `${apiClient.defaults.baseURL}${requestUrl}`;
    
    console.log('🔍 [DEBUG] Request Details:', {
      method: 'GET',
      url: requestUrl,
      fullUrl: fullUrl,
      baseURL: apiClient.defaults.baseURL,
      queryParams: queryParams.toString(),
      params: params,
      timeout: apiClient.defaults.timeout,
      headers: apiClient.defaults.headers
    });

    try {
      console.log('📤 Making request to:', fullUrl);
      const response = await apiClient.get(requestUrl);
      
      console.log('📥 Raw response received:', {
        status: 200, // response interceptor strips status
        data: response,
        dataType: typeof response,
        hasSuccess: 'success' in response,
        successValue: response?.success,
        hasData: 'data' in response,
        dataKeys: response?.data ? Object.keys(response.data) : 'no data object'
      });
      
      // Response interceptor already returns response.data, so 'response' here is the actual data
      // Backend returns: { success: true, message: "...", timestamp: "...", data: { platforms: {...}, pagination: {...} } }
      if (response && response.success && response.data) {
        console.log('✅ Success response processing:', {
          platforms: response.data.platforms ? Object.keys(response.data.platforms) : [],
          itemsCount: response.data.items?.length || 0,
          paginationTotal: response.data.pagination?.total,
          message: response.message
        });
        
        return {
          data: response.data.platforms || response.data.items || [],
          total: response.data.pagination?.total || 0,
          page: response.data.pagination?.page || params.page || 1,
          page_size: response.data.pagination?.page_size || params.page_size || 20,
          success: true,
          message: response.message
        };
      }
      
      console.log('❌ Invalid response format:', response);
      // Handle error response
      return {
        data: [],
        total: 0,
        page: params.page || 1,
        page_size: params.page_size || 20,
        success: false,
        message: response?.message || 'Failed to fetch data'
      };
    } catch (error: any) {
      console.error('❌ [ERROR] Failed to fetch hot items:', error);
      console.error('🔍 [DEBUG] Complete error analysis:', {
        errorType: error?.constructor?.name,
        status: error?.response?.status,
        statusText: error?.response?.statusText,
        data: error?.response?.data,
        message: error?.message,
        code: error?.code,
        config: {
          url: error?.config?.url,
          method: error?.config?.method,
          baseURL: error?.config?.baseURL,
          timeout: error?.config?.timeout
        },
        request: {
          readyState: error?.request?.readyState,
          status: error?.request?.status,
          statusText: error?.request?.statusText,
          responseURL: error?.request?.responseURL
        },
        isAxiosError: error?.isAxiosError,
        toJSON: error?.toJSON ? error.toJSON() : 'no toJSON method'
      });
      
      // Return error response
      return {
        data: [],
        total: 0,
        page: params.page || 1,
        page_size: params.page_size || 20,
        success: false,
        message: error?.response?.data?.message || error?.message || 'Network error'
      };
    }
  }

  // Get hot item detail with comments
  async getHotItemDetail(itemId: string, platform: string): Promise<HotItemDetail> {
    await this.waitForRateLimit();
    return apiClient.get(`/hot-items/${itemId}?platform=${platform}`);
  }

  // Get hot item trends (24 hour heat changes)
  async getHotItemTrends(itemId: string): Promise<HotItemTrend[]> {
    await this.waitForRateLimit();
    return apiClient.get(`/hot-items/trends/${itemId}`);
  }

  // Search hot items
  async searchHotItems(params: SearchHotItemsParams): Promise<ApiResponse<HotItemBase[]>> {
    await this.waitForRateLimit();
    const queryParams = new URLSearchParams();
    
    queryParams.append('keyword', params.keyword);
    if (params.platforms?.length) {
      params.platforms.forEach(p => queryParams.append('platforms', p));
    }
    if (params.page) queryParams.append('page', params.page.toString());
    if (params.page_size) queryParams.append('page_size', params.page_size.toString());

    try {
      const response = await apiClient.get(`/hot-items/search?${queryParams.toString()}`);
      
      // Transform backend response to match frontend interface
      if (response && response.success && response.data) {
        return {
          data: response.data.items || [],
          total: response.data.total || response.data.pagination?.total || 0,
          page: response.data.pagination?.page || params.page || 1,
          page_size: response.data.pagination?.page_size || params.page_size || 20,
          success: true,
          message: response.message
        };
      }
      
      return {
        data: [],
        total: 0,
        page: params.page || 1,
        page_size: params.page_size || 20,
        success: false,
        message: response?.message || 'Failed to search data'
      };
    } catch (error: any) {
      console.error('Failed to search hot items:', error);
      
      return {
        data: [],
        total: 0,
        page: params.page || 1,
        page_size: params.page_size || 20,
        success: false,
        message: error?.response?.data?.message || error?.message || 'Search failed'
      };
    }
  }

  // Toggle favorite status
  async toggleFavorite(itemId: string, isFavorite: boolean): Promise<void> {
    await this.waitForRateLimit();
    if (isFavorite) {
      return apiClient.post(`/hot-items/${itemId}/favorite`);
    } else {
      return apiClient.delete(`/hot-items/${itemId}/favorite`);
    }
  }

  // Get user's favorite items
  async getFavoriteItems(params?: {
    page?: number;
    page_size?: number;
  }): Promise<ApiResponse<HotItemBase[]>> {
    await this.waitForRateLimit();
    const queryParams = new URLSearchParams();
    
    if (params?.page) queryParams.append('page', params.page.toString());
    if (params?.page_size) queryParams.append('page_size', params.page_size.toString());

    return apiClient.get(`/hot-items/favorites?${queryParams.toString()}`);
  }

  // Get aggregated hot items from multiple platforms
  async getAggregatedHotItems(params?: {
    limit?: number;
  }): Promise<HotItemBase[]> {
    await this.waitForRateLimit();
    const queryParams = new URLSearchParams();
    
    if (params?.limit) queryParams.append('limit', params.limit.toString());

    return apiClient.get(`/hot-items/aggregated?${queryParams.toString()}`);
  }
}

export const hotRadarService = new HotRadarService();